package tests;

import static org.junit.Assert.*;

import model.TurtleState;
import model.parser.Parser;
import model.semantics.Node;
import model.turtle.Position;

import java.io.File;
import java.util.*;

import org.junit.Before;
import org.junit.Test;

public class ParserTest {
	private static final String TESTFILE_NAME = "src/tests/parser_test_file";
	private static final char COMMENT_CHAR = '#';
	private static final String DELIMITER = "\\s+";

	private List<Position> myInput;
	private List<String> myExpression;
	private List<Position> myOutput;
	private Parser<Integer> myParser;
	
	private static final int INPUT = 0, EXPRESSION = 1, OUTPUT = 2;

	@Before
	public void setUp() throws Exception {
		myParser = new Parser<Integer>("token", "syntax");
		myInput = new ArrayList<Position>();
		myExpression = new ArrayList<String>();
		myOutput = new ArrayList<Position>();
		
		// Load test file.
		Scanner scan = new Scanner(new File(TESTFILE_NAME));
		
		String line;
		int mode = INPUT;
		while(scan.hasNextLine()) {
			line = scan.nextLine();
			
			if(line.isEmpty() || line.charAt(0) == COMMENT_CHAR || line.matches(DELIMITER)) continue;

			if(mode == INPUT) {
				String[] tokens = line.split(DELIMITER);
				int x = Integer.parseInt(tokens[0]);
				int y = Integer.parseInt(tokens[1]);
				int d = Integer.parseInt(tokens[2]);
				Position p = new Position(x, y, d);
				myInput.add(p);
			} else if(mode == EXPRESSION) {
				myExpression.add(line);
			} else {
				String[] tokens = line.split(DELIMITER);
				int x = Integer.parseInt(tokens[0]);
				int y = Integer.parseInt(tokens[1]);
				int d = Integer.parseInt(tokens[2]);
				Position p = new Position(x, y, d);
				myOutput.add(p);
			}
			mode = (mode+1)%3;
		}

	}

	@Test
	public void testParse() {
		for(int i = 0; i < myInput.size(); i++) {
			Position in = myInput.get(i);
			Node<Integer> root = myParser.parse(myExpression.get(i));
			System.out.println(root.toString());
			TurtleState state = new TurtleState(in);
			root.evaluate(state);
			Position out = state.getTurtle().getPosition();
			assertEquals("Query " + i, myOutput.get(i), out);
		}
	}

}
